import Routes from './routes'
import Navigator from './navigator'
import NavComponent from './components/Navigation'
import { genKey, isObjEqual } from './utils'

let pushRecordIng = false
export default {
  install: (Vue, {router, store, moduleName = 'navigation', keyName = 'VNK'} = {}) => {
    if (!router) {
      console.error('vue-navigation need options: router')
      return
    }

    const bus = new Vue()
    const navigator = Navigator(bus, store, moduleName, keyName)

    // hack vue-router replace for replaceFlag
    const routerReplace = router.replace.bind(router)
    let replaceFlag = false
    router.replace = (location, onComplete, onAbort) => {
      replaceFlag = true
      routerReplace(location, onComplete, onAbort)
    }

    // init router`s keyName
    router.beforeEach((to, from, next) => {
      if (!to.query[keyName]) {
        const query = {...to.query}
        const params = {...to.params}
        // go to the same route will be set the same key
        if (to.path === from.path && isObjEqual(
            {...to.query, [keyName]: null},
            {...from.query, [keyName]: null},
          ) && from.query[keyName]) {
          query[keyName] = from.query[keyName]
        } else {
          query[keyName] = genKey()
        }
        next({name: to.name, query, params, replace: replaceFlag || !from.query[keyName]})
      } else {
        navigator.record(to, from, replaceFlag)
        replaceFlag = false
        next()
      }
    })

    Vue.component('navigation', NavComponent(keyName))

    Vue.navigation = Vue.prototype.$navigation = {
      on: (event, callback) => {
        bus.$on(event, callback)
      },
      once: (event, callback) => {
        bus.$once(event, callback)
      },
      off: (event, callback) => {
        bus.$off(event, callback)
      },
      getRoutes: () => Routes.slice(),
      cleanRoutes: () => navigator.reset()
    }
  }
}

function addQuery (url = location.href, query) {
  const _query = url.match(/#[^#\?]*\?([^#\/]*)?/)
  const isReplace = _query ? true: false
  const str = _query ? _query[1]: ''
  let queryArray = str.match(/([^&=]*=[^&=]*)/g) || []
  const queryObj = {}
  queryArray.forEach(item => {
    const [k, v] = item.split('=')
    queryObj[k] = v
  })
  Object.assign(queryObj, query)
  queryArray = Object.keys(queryObj).map(k => [k+'='+queryObj[k]])
  const str2 = queryArray.join('&')
  return url.replace(str, str2)
}